package queue_sim

import "gitee.com/tfcolin/dsg"

type ServiceTimer func (id int) float64
type ServiceTransProbFunc func (id int, qlen []int) []float64

type ServiceInfo struct {
	ns int
	timer ServiceTimer
	trans ServiceTransProbFunc
	num_su []int
}

type ServiceSignal struct {
      sid  int
      time float64
      updown int
}

type ServiceStatus struct {
	time float64
	qlen []int
	load []int
}

type ServiceSimulationResult []ServiceStatus

type ServiceSimulationUI interface {
      SimulationStart ()
      ShowStatus (ass ServiceStatus, end_time float64)
      SimulationEnd ()
}

func ZeroServiceTransProbFunc  (id int, qlen []int) []float64 {
	var zeros []float64 = make ([]float64, len(qlen)) 
	return zeros
}

func (ass ServiceSimulationResult) Len () int {
      return len(ass)
}
func (ass ServiceSimulationResult) Less (i, j int) bool {
      return ass[i].time < ass[j].time
}
func (ass ServiceSimulationResult) Swap (i, j int) {
      ass[i], ass[j] = ass[j], ass[i]
}

func ServiceStatusCompFunc (x1 dsg.Value, x2 dsg.Value) int {
	if (x1.(ServiceSignal).time < x2.(ServiceSignal).time) {
		return -1
	} else if (x1.(ServiceSignal).time > x2.(ServiceSignal).time) {
		return 1
	} else {
		return 0
	}
}

func MakePoissonServiceTimer (lambda []float64) ServiceTimer {
	coef := make ([]float64, len (lambda))
	copy (coef, lambda)
	return func (id int) float64 {
		return ExpDist(coef[id])
	}
}

func (ss * ServiceStatus) Init (ns int) {
	ss.time = 0
	ss.qlen = make ([]int, ns)
	ss.load = make ([]int, ns)
}

func (res ServiceSimulationResult) GetEndTime () float64 {
	return res[len(res) - 1].time * 1.01
}

func InitServiceInfo () (num_location int, timer ServiceTimer, trans ServiceTransProbFunc, num_serv_unit []int) * ServiceInfo {
	si := ServiceInfo {
		ns : num_location,
		timer : timer,
		trans : trans,
	}
	copy (si.num_su, num_serv_unit[:num_location])

	return &si
}

